/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.api.changeset;

import com.inspur.edp.bef.api.action.determination.IDeterminationContext;
import com.inspur.edp.bef.api.action.validation.IValidationContext;
import com.inspur.edp.cef.entity.changeset.AddChangeDetail;
import com.inspur.edp.cef.entity.changeset.AddedChildChangeCollection;
import com.inspur.edp.cef.entity.changeset.DeleteChangeDetail;
import com.inspur.edp.cef.entity.changeset.DeletedChildChangeCollection;
import com.inspur.edp.cef.entity.changeset.IChangeDetail;
import com.inspur.edp.cef.entity.changeset.ModifyChangeDetail;
import com.inspur.edp.cef.entity.dependenceTemp.DataValidator;
import com.inspur.edp.cef.entity.entity.IEntityData;
import com.inspur.edp.cef.entity.entity.IEntityDataCollection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;

public class Util {
  //TODO: 此方法与下面方法逻辑类似
  public static Iterable<IChangeDetail> getChildChanges(
      IChangeDetail change, String childCode, IDeterminationContext dtmCtx) {
    Objects.requireNonNull(change, "change");
    Objects.requireNonNull(dtmCtx, "dtmCtx");
    DataValidator.checkForEmptyString(childCode, "childCode");

    switch (change.getChangeType()) {
      case Deleted:
        return dtmCtx.getOriginalData() == null ? Collections.emptyList()
            : new DeletedChildChangeCollection((DeleteChangeDetail) change,
                dtmCtx.getTransactionData() != null ? dtmCtx.getTransactionData()
                    : dtmCtx.getOriginalData(), childCode);
      case Modify:
        Map<String, IChangeDetail> childChange = ((ModifyChangeDetail)change).getChildChanges().get(childCode);
        return childChange == null ? new ArrayList<>() : childChange.values();
      case Added:
        return new AddedChildChangeCollection((AddChangeDetail) change, childCode);
      default:
        throw new UnsupportedOperationException("change.ChangeType" + change.getChangeType());
    }
  }

  //TODO: 此方法与上面方法逻辑类似
  public static Iterable<IChangeDetail> getChildChanges(
      IChangeDetail change, String childCode, IValidationContext ctx) {
    Objects.requireNonNull(change, "change");
    Objects.requireNonNull(ctx, "ctx");
    DataValidator.checkForEmptyString(childCode, "childCode");

    switch (change.getChangeType()) {
      case Deleted:
        return ctx.getOriginalData() == null ? Collections.emptyList()
            : new DeletedChildChangeCollection((DeleteChangeDetail) change, ctx.getOriginalData(),
                childCode);
      case Modify:
        if (((ModifyChangeDetail)change).getChildChanges() == null){
          return new ArrayList<IChangeDetail>();
        }
        Map<String, IChangeDetail> childChange = ((ModifyChangeDetail)change).getChildChanges().get(childCode);
        if(childChange == null){
          return new ArrayList<IChangeDetail>();
        }
        return childChange.values();
      case Added:
        return new AddedChildChangeCollection((AddChangeDetail) change, childCode);
      default:
        throw new UnsupportedOperationException("change.ChangeType" + change.getChangeType());
    }
  }

  public static IChangeDetail getChildChange(IChangeDetail change, String childCode, String childId) {
    Objects.requireNonNull(change, "change");
    Objects.requireNonNull(childCode, "childCode");
    Objects.requireNonNull(childId, "childId");
    switch(change.getChangeType()) {
      case Deleted:
        return new DeleteChangeDetail(childId);
      case Modify:
        if (((ModifyChangeDetail)change).getChildChanges() == null) {
          return null;
        } else {
          Map<String, IChangeDetail> childChange = (Map)((ModifyChangeDetail)change).getChildChanges().get(childCode);
          return childChange != null ? childChange.get(childId) : null;
        }
      case Added:
        IEntityData childData = ((IEntityDataCollection)((AddChangeDetail)change).getEntityData().getChilds().get(childCode)).tryGet(childId);
        return childData == null ? null : new AddChangeDetail(childData);
      default:
        throw new UnsupportedOperationException("change.ChangeType" + change.getChangeType().toString());
    }
  }
}
